package org.jeecg.modules.miniAppCustomerEndPoint.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.miniAppCustomerEndPoint.constant.JxCustomerConstant;
import org.jeecg.modules.miniAppCustomerEndPoint.entity.*;
import org.jeecg.modules.miniAppCustomerEndPoint.mapper.JxOrderDetailMapper;
import org.jeecg.modules.miniAppCustomerEndPoint.mapper.JxOrderMapper;
import org.jeecg.modules.miniAppCustomerEndPoint.mapper.JxShoppingCartMapper;
import org.jeecg.modules.miniAppCustomerEndPoint.mapper.JxSiteMenuMapper;
import org.jeecg.modules.miniAppCustomerEndPoint.service.JxOrderServiceImpl;
import org.jeecg.modules.miniAppCustomerEndPoint.utils.JxUserUtil;
import org.jeecg.modules.platformMasterEndPoint.entity.*;
import org.jeecg.modules.platformMasterEndPoint.mapper.*;
import org.jeecg.modules.platformMasterEndPoint.utils.JxOrderUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@Api(tags = "订单")
@RestController
@RequestMapping("/jx/jxOrder")
@Slf4j
public class JxOrderController {

    @Autowired
    private JxOrderDetailMapper jxOrderDetailMapper;

    @Autowired
    private JxShoppingCartMapper jxShoppingCartMapper;

    @Autowired
    private JxOrderServiceImpl jxOrderServiceImpl;

    @Autowired
    private JxOrderMapper jxOrderMapper;

    @Autowired
    private JxFoodRepositoryMapper jxFoodRepositoryMapper;

    @Autowired
    private JxSiteMenuMapper jxSiteMenuMapper;

    @Autowired
    private JxStoreRepositoryMapper jxStoreRepositoryMapper;

    @Autowired
    private JxCouponMapper jxCouponMapper;

    @Autowired
    private JxSiteDetailMapper jxSiteDetailMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private JxSysConfigMapper jxSysConfigMapper;

    @Autowired
    private JxAfterSalesMapper jxAfterSalesMapper;

    @Value("${jx.afterSaleSeviceVersion}")
    private String afterSaleServiceVersion;


    @ApiOperation(value = "某个站点已下单订单数量", notes = "展示在首页，某个站点已下单订单量")
    @GetMapping(value = "/queryPayedOrderCount")
    public Result<?> queryPayedOrderCountBySiteAddrId(@RequestParam("siteAddrId") String siteId) {

        // 每天晚上12点，前一天的订单的状态都会从 pay 更新成 completed；因此，状态为 pay的订单，一定是当天已经支付的
        int payedOrderCount = jxOrderDetailMapper.queryPayedOrdersCount(siteId, JxOrderUtil.todayFlagForIndex());
        HashMap<String, Integer> resultData = new HashMap<>();
        resultData.put("payedOrderCount", payedOrderCount);
        return Result.ok(resultData);
    }

    @ApiOperation(value = "分页查看已下单的订单简介", notes = "首页用户点击查看详情，弹窗中展示已经下单的订单简介")
    @GetMapping(value = "/queryPayedOrderBriefDescription")
    public Result<?> queryPayedOrderBriefDescription(
            @RequestParam("siteAddrId") String siteId,
            @RequestParam("pageNo") Integer pageNo,
            @RequestParam("pageSize") Integer pageSize) {

        int count = jxOrderDetailMapper.queryPayedOrdersCount(siteId, JxOrderUtil.todayFlagForIndex());
        List<HashMap<String, Object>> pageList = jxOrderDetailMapper.queryPayedOrders(siteId, JxOrderUtil.todayFlagForIndex(), (pageNo - 1) * pageSize, pageSize);

        HashMap<String, Object> resultData = new HashMap<>();
        resultData.put("totalCount", count);
        resultData.put("pageNo", pageNo);
        resultData.put("pageSize", pageSize);
        int pageCount = count / pageSize;
        int totalPages = pageCount == 0 ? pageCount : pageCount + 1;
        resultData.put("pages", totalPages);
        List<HashMap<String, Object>> formatedOrderList = new ArrayList<>();
        for (int i = 0; i < pageList.size(); i++) {
            HashMap<String, Object> payedOrderBriefInfo = pageList.get(i);
            HashMap<String, Object> formatedOrderDetail = new HashMap<>();
            formatedOrderDetail.put("nickName", payedOrderBriefInfo.get("nameTakingMeal"));
            formatedOrderDetail.put("foodName", payedOrderBriefInfo.get("foodName"));
            formatedOrderDetail.put("payTime", payedOrderBriefInfo.get("payTime"));
            formatedOrderList.add(formatedOrderDetail);
        }
        resultData.put("orders", formatedOrderList);
        return Result.ok(resultData);
    }

    @ApiOperation(value = "添加菜品到购物车", notes = "点击进入店铺内，选择某个菜品以及规格后，点击确定后，加入购物车")
    @PostMapping(value = "/addShoppingCart")
    public Result<?> addShoppingCart(
            HttpServletRequest request,
            @RequestBody JxShoppingCartFoodVo foodVo) {

        String token = request.getHeader("X-Access-Token");
        String userId = JxUserUtil.getUserId(token, null);

        HashMap<String, String> resultData = new HashMap<>();
        Integer dateFlag = JxOrderUtil.todayFlagForIndex();
        LambdaQueryWrapper<JxShoppingCartFoodDo> queryWrapper = new LambdaQueryWrapper<JxShoppingCartFoodDo>()
                .eq(JxShoppingCartFoodDo::getDateFlag, dateFlag)
                .eq(JxShoppingCartFoodDo::getSiteId, foodVo.getSiteAddressId())
                .eq(JxShoppingCartFoodDo::getUserId, userId)
                .eq(JxShoppingCartFoodDo::getDelFlag, 0);
        String foodPrintName = null;
        if (foodVo.getSpecification().isEmpty()) {
            // 当菜品的规格列表为空数组时，表示不是自选套餐，而是 盒饭，最终打印在标签上的菜品名就是 foodName，需要根据foodId判断是否合并
            queryWrapper.eq(JxShoppingCartFoodDo::getFoodId, foodVo.getFoodId());
        } else {
            foodPrintName = jxOrderServiceImpl.buildFoodPrintNameFromSpecification(foodVo.getSpecification());
            queryWrapper.eq(JxShoppingCartFoodDo::getFoodId, foodVo.getFoodId());
            queryWrapper.eq(JxShoppingCartFoodDo::getFoodPrintName, foodPrintName); // 根据最终打印在标签纸上的菜品名来判断 是否已经有同种类型的菜品，是新增记录还是 仅增加份数
        }

        List<JxShoppingCartFoodDo> list = jxShoppingCartMapper.selectList(queryWrapper);
        if (list != null && list.size() > 0) {
            // 若购物车中已有此菜品，即用户订购了多份同类菜品
            JxShoppingCartFoodDo jxShoppingCartFoodDo = list.get(0);
            // 通过这里可以通过购物车中某条记录的价格和份数计算出来 菜品单价，避免通过访问 jx_site_menu 表，减少db操作
            int oneFoodPrice = jxShoppingCartFoodDo.getSalePrice() / jxShoppingCartFoodDo.getCount();
            int count = jxShoppingCartFoodDo.getCount();
            int newCount = count + foodVo.getCount();
            int totalSalePrice = newCount * oneFoodPrice;
            try{
                // 若购物车表中已经有，需要将份数count 加1，sale_price 也要对应的累加
                int updateCount = jxShoppingCartMapper.updateShoppingCartItemWhenAddOrRemoveFood(dateFlag, foodVo.getSiteAddressId(), userId,
                        foodVo.getFoodId(),foodPrintName, newCount, totalSalePrice);
                if (updateCount == 1) {
                    log.info("成功将商品{} 添加都购物车, 同类菜品已存在，仅将份数加1", foodVo.getFoodId());
                } else {
                    log.error("将商品{} 添加都购物车失败", foodVo.getFoodId());
                    return Result.error("添加都购物车失败，请联系后台技术人员进行定位");
                }
            } catch (Exception ex) {
                log.error("{}", ex);
                return Result.error("添加都购物车失败，出现异常，请联系后台技术人员进行处理");
            }
        } else {
            // 购物车没有 此foodid的菜品，向购物车中新增一条记录;
            JxShoppingCartFoodDo foodDo = new JxShoppingCartFoodDo();
            foodDo.setUserId(userId);
            foodDo.setSiteId(foodVo.getSiteAddressId());
            JxFoodRepositoryDo foodRepositoryDo = jxFoodRepositoryMapper.selectById(foodVo.getFoodId());
            if (foodRepositoryDo == null) {
                log.error("添加到购物车中的菜品 {} 所属店铺信息在店铺信息库中查找不到", foodVo.getFoodId());
                return Result.error("添加到购物车中的菜品所属店铺信息在店铺信息库中查找不到");
            }
            foodDo.setStoreId(foodRepositoryDo.getStoreId());
            foodDo.setStoreName(foodRepositoryDo.getStoreName());
            foodDo.setFoodId(foodVo.getFoodId());
            foodDo.setFoodName(foodVo.getFoodName());
            foodDo.setFoodPrintName(foodPrintName);
            foodDo.setCount(foodVo.getCount());
            foodDo.setSpecification(foodVo.getSpecification().toJSONString());
            foodDo.setSalePrice(foodVo.getSalePrice());
            foodDo.setDelFlag((byte) 0);
            foodDo.setDateFlag(dateFlag);
            foodDo.setCreateTime(new Date());
            foodDo.setUpdateTime(new Date());

            try {
                int count = jxShoppingCartMapper.insert(foodDo);
                log.info("向用户: {} 购物车中添加菜品成功，添加记录个数: {}, 购物车商品id: {}", userId, count, foodDo.getId());
            } catch (Exception ex) {
                log.info("request body: {}", foodVo);
                log.error("", ex);
                return Result.error(ex.getMessage());
            }
            // 将添加到购物车中的商品，在购物车表中的唯一id返回给前端，当需要删除时，传递此参数删除记录
            resultData.put("shoppingCartId", foodDo.getId());
        }

        return Result.ok(resultData);
    }

    /**
     * 点击进入店铺内，点击菜品的-号，或者在【购物车】页面，点击 - 号移除菜品
     * @param request
     * @param siteId
     * @param foodId
     * @param count 页面上点击 - 号，调用接口，此字段值为1，为了后期可能的扩展（允许通过其他方式调用该接口时，count可以传递大于1的其他值）
     * @return
     */
    @ApiOperation(value = "从购物车中移除菜品", notes = "点击进入店铺内，取消选择某个菜品以及规格后，从购物车移除；或者在【购物车】页面，移除菜品")
    @DeleteMapping(value = "/removeShoppingCart")
    public Result<?> removeShoppingCart(
            HttpServletRequest request,
            @RequestParam("siteId") String siteId,
            @RequestParam("foodId") String foodId,
            @RequestParam(value = "specification", required = false, defaultValue = "[]") String specificationStr,
            @RequestParam("count") int count) {

        log.info("in removeShoppingCart, siteId: {}, foodId: {}, specification: {}, count: {}", siteId, foodId, specificationStr, count);
        String token = request.getHeader("X-Access-Token");
        String userId = JxUserUtil.getUserId(token, null);
        Integer dateFlag = JxOrderUtil.todayFlagForIndex();
        LambdaQueryWrapper<JxShoppingCartFoodDo> queryWrapper = new LambdaQueryWrapper<JxShoppingCartFoodDo>()
                .eq(JxShoppingCartFoodDo::getDateFlag, dateFlag)
                .eq(JxShoppingCartFoodDo::getSiteId, siteId)
                .eq(JxShoppingCartFoodDo::getUserId, userId)
                .eq(JxShoppingCartFoodDo::getDelFlag, 0);
        String foodPrintName = null;
        JSONArray specification = JSONArray.parseArray(specificationStr);
        if (specification.isEmpty()) {
            // 当菜品的规格列表为空数组时，表示不是自选套餐，而是 盒饭，最终打印在标签上的菜品名就是 foodName，仅需要根据foodId判断是否为相同菜品，是移除菜品项，还是仅仅修改份数
            queryWrapper.eq(JxShoppingCartFoodDo::getFoodId, foodId);
        } else {
            foodPrintName = jxOrderServiceImpl.buildFoodPrintNameFromSpecification(specification);
            queryWrapper.eq(JxShoppingCartFoodDo::getFoodId, foodId);
            queryWrapper.eq(JxShoppingCartFoodDo::getFoodPrintName, foodPrintName); // 根据最终打印在标签纸上的菜品名来判断 是否已经有同种类型的菜品，是新增记录还是 仅增加份数
        }

        List<JxShoppingCartFoodDo> list = jxShoppingCartMapper.selectList(queryWrapper);
        if (list != null && list.size() > 0) {
            JxShoppingCartFoodDo jxShoppingCartFoodDo = list.get(0);
            if (jxShoppingCartFoodDo.getCount() > 1) {
                int oneFoodPrice = jxShoppingCartFoodDo.getSalePrice() / jxShoppingCartFoodDo.getCount();
                int newCount = jxShoppingCartFoodDo.getCount() - count;
                int totalSalePrice = newCount * oneFoodPrice;
                int updateCount = jxShoppingCartMapper.updateShoppingCartItemWhenAddOrRemoveFood(dateFlag, siteId, userId,
                        foodId, foodPrintName, newCount, totalSalePrice);
                if (updateCount == 1) {
                    log.info("更新购物车中该菜品的份数成功");
                    return Result.ok("从购物车中减少菜品成功");
                } else {
                    return Result.error("从购物车移除菜品失败，请联系后台技术人员进行处理");
                }
            } else {
                // 只是标记删除
                int deleteCount = jxShoppingCartMapper.deleteShoppingCartByFlag(dateFlag, siteId, userId, foodId, foodPrintName);
                if (deleteCount == 1) {
                    log.info("成功从购物车移除菜品，仅标记删除");
                    return Result.ok("将菜品从购物车删除成功");
                } else {
                    log.info("从购物车移除菜品失败");
                    return Result.error("从购物车移除菜品失败，请联系后台技术人员进行处理");
                }
            }
        } else {
            log.error("购物车表中无此用户id：{}，站点id：{}， dateFlag：{}， 菜品id：{} 的菜品，无法删除购物车中的该菜品", userId, siteId, dateFlag, foodId);
            return Result.ok();
        }
    }

    @ApiOperation(value = "查看购物车", notes = "查看购物车中选中的菜品")
    @GetMapping(value = "/showShoppingCart")
    public Result<?> queryShoppingCart(
            HttpServletRequest request,
            @RequestParam("siteAddrId") String siteAddrId,
            @RequestParam(value = "userId", required = false, defaultValue = "") String userId,
            @RequestParam("pageNo") Integer pageNo,
            @RequestParam("pageSize") Integer pageSize) {
        String token = request.getHeader("X-Access-Token");
        String userId2 = JxUserUtil.getUserId(token, userId);
        Page<JxShoppingCartFoodDo> page = new Page(pageNo, pageSize);

        Page<JxShoppingCartFoodDo> pageList = jxShoppingCartMapper.selectPage(page, new LambdaQueryWrapper<JxShoppingCartFoodDo>()
                .eq(JxShoppingCartFoodDo::getDateFlag, JxOrderUtil.todayFlagForIndex())
                .eq(JxShoppingCartFoodDo::getUserId, userId2)
                .eq(JxShoppingCartFoodDo::getSiteId, siteAddrId)
                .eq(JxShoppingCartFoodDo::getDelFlag, 0));

        HashMap<String, Object> resultData = new HashMap<>();
        List<HashMap<String,Object>> formatedFoodList = new ArrayList<>();
        if (pageList != null) {
            for (int i = 0 ; i < pageList.getRecords().size(); i ++) {
                JxShoppingCartFoodDo shoppingCartFoodDo = pageList.getRecords().get(i);
                HashMap<String,Object> formatedData = new HashMap<>();
                formatedData.put("shoppingCartId", shoppingCartFoodDo.getId());
                formatedData.put("foodId", shoppingCartFoodDo.getFoodId());
                formatedData.put("foodName", shoppingCartFoodDo.getFoodName());
                // todo 需要修改成从redis中获取菜品的静态信息，通过查询db获取菜品静态信息，性能太差
                JxFoodRepositoryDo jxFoodRepositoryDo = jxFoodRepositoryMapper.selectById(shoppingCartFoodDo.getFoodId());
                if (jxFoodRepositoryDo != null) {
                    formatedData.put("foodImage", jxFoodRepositoryDo.getImage());
                } else {
                    log.error("无法从菜品库中查找到id为 {} 的菜品信息，使用默认的菜品图片", shoppingCartFoodDo.getFoodId());
                    formatedData.put("foodImage", JxCustomerConstant.FOOD_DEFAULT_IMAGE);
                }

                // todo 从redis中获取
                List<JxSiteMenuDo> siteMenuDos = jxSiteMenuMapper.selectList(new LambdaQueryWrapper<JxSiteMenuDo>().eq(JxSiteMenuDo::getFoodId, shoppingCartFoodDo.getFoodId()));
                if (siteMenuDos != null && siteMenuDos.size() > 0) {
                    JxSiteMenuDo siteMenuDo = siteMenuDos.get(0);
                    formatedData.put("foodPrice", siteMenuDo.getSalePrice());
                    formatedData.put("storeId", siteMenuDo.getStoreId());
                    // todo 从redis中获取
                    JxStoreRepositoryDo storeRepositoryDo = jxStoreRepositoryMapper.selectById(siteMenuDo.getStoreId());
                    formatedData.put("storeName", storeRepositoryDo.getStoreName());
                    // 返回用户选中的规格，用户添加菜品到购物车时，会传递那些规格被选中了，当查询时，返回添加购物车时，传递的规格即可
                    formatedData.put("specifications", JSONArray.parseArray(shoppingCartFoodDo.getSpecification()));
                } else {
                    log.error("无法从菜品库中查找到id为 {} 的菜品信息，无法获取菜品价格，跳过此菜品，尽快联系后台技术人员进行处理", shoppingCartFoodDo.getFoodId());
                    continue;
                }
                formatedData.put("count", shoppingCartFoodDo.getCount());
                formatedFoodList.add(formatedData);
            }
            resultData.put("totalCount", pageList.getTotal());
            resultData.put("pageNo", pageList.getCurrent());
            resultData.put("pageSize", pageList.getSize());
            resultData.put("pages", pageList.getPages());
            resultData.put("shoppingCart", formatedFoodList);
        } else {
            log.error("大厦id: {}, 用户id: {} 购物车中的商品为空", siteAddrId, userId2);
        }

        return Result.ok(resultData);
    }

    @GetMapping("/queryOrderSummary")
    public Result<?> queryOrderSummary(
            HttpServletRequest request,
            @RequestParam(value = "userId", required = false) String userIdForDebug) {
        String token = request.getHeader("X-Access-Token");
        String userId = JxUserUtil.getUserId(token, userIdForDebug);

        JSONObject resultData = jxOrderServiceImpl.queryOrderSummary(userId);
        return Result.ok(resultData);
    }

    /**
     * 我的页面，查看所有，待支付，待发货，待收货，待评价订单; 0 所有订单; 1 待付款订单; 2 待发货订单; 3 待收货订单; 4 待评价订单
     * 仅展示当天的订单
     * @return
     */
    @GetMapping("/queryOrderDetails")
    public Result<?> queryOrderDetailsByTypeId(
            HttpServletRequest request,
            @RequestParam(value = "userId", required = false) String userIdForDebug,
            @RequestParam("type") Integer orderType) {

        String token = request.getHeader("X-Access-Token");
        String userId = JxUserUtil.getUserId(token, userIdForDebug);

        List<JxOrderDo> list1 = null;
        if (orderType == 0) {
            // 0 表示查看所有订单; 可以看到所有历史订单，而不只是当天的订单
            list1 = jxOrderMapper.selectList(new LambdaQueryWrapper<JxOrderDo>()
                    .eq(JxOrderDo::getUserId, userId)
                    .select(JxOrderDo::getId, JxOrderDo::getState, JxOrderDo::getCouponIds, JxOrderDo::getCreateTime));
        } else {
            String orderTypeString = jxOrderServiceImpl.mapOrderTypeCode2String(orderType);
            // 非0 表示仅查看特定状态的订单; 可以看到所有历史订单，而不只是当天的订单
            list1 = jxOrderMapper.selectList(new LambdaQueryWrapper<JxOrderDo>()
                    .eq(JxOrderDo::getUserId, userId)
                    .eq(JxOrderDo::getState, orderTypeString)
                    .select(JxOrderDo::getId, JxOrderDo::getState, JxOrderDo::getCouponIds, JxOrderDo::getCreateTime));
        }

        JxSiteDetailDo jxSiteDetailDo = null;

        JSONObject resultData = new JSONObject();
        for (int i = 0 ; i < list1.size(); i ++) {
            List<JSONObject> oneOrder = new ArrayList<>();
            JxOrderDo jxOrderDo = list1.get(i);

            // todo 优化时，需要将所以的 全局配置项，归类到一个表中进行管理，而不是使用各个表中的数据来 作为这些全局属性的值
            if (jxSiteDetailDo == null) {
                // 此处对 jx_site_detail 表的查询是在 for循环内，只需要查询一次即可，因此，通过 jxSiteDetailDo是否为null 防止每次for循环都执行sql
                String siteId = jxOrderDo.getSiteId();
                jxSiteDetailDo = jxSiteDetailMapper.selectById(siteId);
                if (jxSiteDetailDo == null) {
                    // 特殊场景下，如果 站点信息表中查询不到站点信息，那就 创建一个对象，赋一个默认值，这样 jxSiteDetailDo 就不为null了，就不用在 每次for循环中执行sql了
                    jxSiteDetailDo = new JxSiteDetailDo();
                    jxSiteDetailDo.setSupplyTimeSpan("{\"beginTime\":\"19:00:00\", \"endTime\":\"10:30:00\"}");
                }
            }
            List<JxOrderDetailDo> list2 = jxOrderDetailMapper.selectList(new LambdaQueryWrapper<JxOrderDetailDo>().eq(JxOrderDetailDo::getOrderId, jxOrderDo.getId()));
            for (int k =0 ; k < list2.size() ; k ++) {
                JxOrderDetailDo orderDetailDo = list2.get(k);
                List<JxFoodRepositoryDo> list3 = jxFoodRepositoryMapper.selectList(new LambdaQueryWrapper<JxFoodRepositoryDo>().eq(JxFoodRepositoryDo::getId, orderDetailDo.getFoodId()));
                if (list3 != null && list3.size() > 0) {
                    JxFoodRepositoryDo jxFoodRepositoryDo = list3.get(0);
                    JSONObject formatedFood = new JSONObject();
                    // 菜品所属订单id
                    formatedFood.put("orderId", orderDetailDo.getOrderId());
                    formatedFood.put("foodName", jxFoodRepositoryDo.getFoodName());
                    formatedFood.put("foodImage", jxFoodRepositoryDo.getImage());
                    formatedFood.put("foodPrice", orderDetailDo.getSalePrice());
                    formatedFood.put("count", orderDetailDo.getCount());
                    if (jxOrderDo.getCouponIds() != null && !jxOrderDo.getCouponIds().isEmpty()) {
                        String[] coupons = jxOrderDo.getCouponIds().split(",");
                        String usedCouponId = coupons[0];
                        // todo 从redis中获取
                        JxCouponDo jxCouponDo = jxCouponMapper.selectById(usedCouponId);
                        formatedFood.put("couponValue", jxCouponDo.getCouponValue());
                    } else {
                        formatedFood.put("couponValue", 0);
                    }

                    formatedFood.put("orderTime", orderDetailDo.getCreateTime());
                    formatedFood.put("type", jxOrderDo.getState().getValue());
                    // todo 添加系统配置表，存放这些全局配置
                    // 订单取消截止时间，在此时间之前，订单可以取消，并原路返回用户支付的金额，超过后 【取消订单】按钮不可见
                    String canCancelTime = jxOrderServiceImpl.calcOrderCanCancelTime(jxOrderDo.getCreateTime(), jxSiteDetailDo.getSupplyTimeSpan());
                    formatedFood.put("canCancelTime", canCancelTime);

                    oneOrder.add(formatedFood);
                }
            }
            resultData.put(jxOrderDo.getId(), oneOrder);
        }

        if (resultData == null && resultData.size() == 0) {
            log.warn("未找到用户: {}, 类型为： {} 的订单", userId, orderType);
        }

        return Result.ok(resultData);
    }


    /**
     * 接口 3.12 当用户点击 订单中心某个订单 的 【再来一单】 按钮，跳转到 购物车页面 时，调用此接口，根据用户之前的订单id，获取到 用户之前选购的商品信息
     * @return
     */
    @GetMapping("/queryOrderDetailWhenTryAgain")
    public Result<?> queryOrderDetailWhenTryAgain(
            HttpServletRequest request,
            @RequestParam(value = "userId", required = false) String userIdForDebug,
            @RequestParam(value = "orderId") String orderId) {

        String token = request.getHeader("X-Access-Token");
        String userId = JxUserUtil.getUserId(token, userIdForDebug);
        String siteId = "";
        List<JxOrderDetailDo> list = jxOrderDetailMapper.selectList(new LambdaQueryWrapper<JxOrderDetailDo>().eq(JxOrderDetailDo::getOrderId, orderId));
        // 根据之前订单id，查询之前订单包含的菜品，然后 将菜品添加到购物车中，然后跳转到购物车页面，购物车的接口就能够复用了; 而且用户可以对购物车进行添加，移除，就完全可以复用操作流程了，不需要额外添加其他接口
        for (int k = 0; k < list.size(); k ++) {
            JxOrderDetailDo jxOrderDetailDo = list.get(k);
            JxShoppingCartFoodVo jxShoppingCartFoodVo = new JxShoppingCartFoodVo();

            jxShoppingCartFoodVo.setSiteAddressId(jxOrderDetailDo.getSiteId());
            jxShoppingCartFoodVo.setStoreId(jxOrderDetailDo.getStoreId());
            // todo 使用redis中数据
            siteId = jxOrderDetailDo.getSiteId();
            JxStoreRepositoryDo storeRepositoryDo = jxStoreRepositoryMapper.selectById(jxOrderDetailDo.getStoreId());
            if (storeRepositoryDo == null) {
                log.error("无法找到店铺 {} 的数据", jxOrderDetailDo.getStoreId());
                jxShoppingCartFoodVo.setStoreName("unknown");
            } else {
                jxShoppingCartFoodVo.setStoreName(storeRepositoryDo.getStoreName());
            }
            jxShoppingCartFoodVo.setFoodId(jxOrderDetailDo.getFoodId());
            // todo 使用redis中数据
            JxFoodRepositoryDo foodRepositoryDo = jxFoodRepositoryMapper.selectById(jxOrderDetailDo.getFoodId());
            if (foodRepositoryDo == null) {
                log.error("无法找到菜品 {} 的数据", jxOrderDetailDo.getFoodId());
                jxShoppingCartFoodVo.setFoodName("unknown");
            } else {
                jxShoppingCartFoodVo.setFoodName(foodRepositoryDo.getFoodName());
            }
            jxShoppingCartFoodVo.setCount(jxOrderDetailDo.getCount());
            jxShoppingCartFoodVo.setSalePrice(jxOrderDetailDo.getSalePrice() * jxOrderDetailDo.getCount());
            jxShoppingCartFoodVo.setSpecification(JSONArray.parseArray(jxOrderDetailDo.getSpecification()));
            addShoppingCart(request, jxShoppingCartFoodVo);
        }

        // 前面的操作替用户将商品添加到购物车，此再从购物车中查询出用户购物车中的商品
        Result<?> result = queryShoppingCart(request, siteId, userId, 1, 10);

        return result;
    }

    /**
     * 接口 3.13 提交评价
     * @return
     */
    @PostMapping("/submitOrderReview")
    public Result<?> submitOrderReview(@RequestBody() JSONObject requestBody) {

        JxOrderDo orderDo = new JxOrderDo();

        String orderId = requestBody.getString("orderId");
        orderDo.setFlavorScore(requestBody.getFloatValue("flavor"));
        orderDo.setQuantityScore(requestBody.getFloatValue("quantity"));
        orderDo.setDeliveryScore(requestBody.getFloatValue("delivery"));
        String msg = requestBody.getString("msg");
        String truncateMsg = msg.length() > 120 ? msg.substring(0, 120) : msg;
        orderDo.setReviewMsg(truncateMsg); // 仅返回前120个内容

        try {
            jxOrderMapper.update(orderDo, new UpdateWrapper<JxOrderDo>().eq("id", orderId));
            return Result.ok("评价提交成功");
        } catch (Exception ex) {
            log.error("{}", ex);
            return Result.error("评价提交失败");
        }
    }

    /**
     * 接口 3.14 查询评价
     * @return
     */
    @GetMapping("/queryOrderReview")
    public Result<?> queryOrderReview(
            @RequestParam("orderId") String orderId) {

        JSONObject resultData = new JSONObject();
        try {
            JxOrderDo orderDo = jxOrderMapper.selectById(orderId);

            resultData.put("flavor", orderDo.getFlavorScore());
            resultData.put("quantity", orderDo.getQuantityScore());
            resultData.put("delivery", orderDo.getDeliveryScore());
            resultData.put("msg", orderDo.getReviewMsg());
            resultData.put("reviewTime", orderDo.getUpdateTime());
            return Result.ok(resultData);
        } catch (Exception ex) {
            log.error("{}", ex);
            return Result.error("查询评价失败");
        }
    }


    /**
     * 接口 3.19 获取售后赔偿项及赔偿标准
     * @param request
     * @return
     */
    @GetMapping("/queryAfterSaleServiceRules")
    public Result<?> queryAfterSaleServiceRules(
            HttpServletRequest request,
            @RequestParam("orderId") String orderId) {

        if (afterSaleServiceVersion == null || afterSaleServiceVersion.isEmpty()) {
            afterSaleServiceVersion = "after-sale-service-v1";
        }

        List<JxSysConfigDo> afterSaleServices = jxSysConfigMapper.selectList(new LambdaQueryWrapper<JxSysConfigDo>().eq(JxSysConfigDo::getConfigKey, afterSaleServiceVersion));
        if (afterSaleServices != null && afterSaleServices.size() > 0) {
            JxOrderDo jxOrderDo = jxOrderMapper.selectById(orderId);
            String afterSaleServiceContent = afterSaleServices.get(0).getConfigValue();
            JSONArray afterSales = JSONArray.parseArray(afterSaleServiceContent);
            for (int k = 0 ; k < afterSales.size(); k ++) {
                JSONObject afterSaleItem = afterSales.getJSONObject(k);
                if (afterSaleItem.getIntValue("flag") == 1) {
                    // 售后赔付项中，有些是按照订单原价赔付，此时需要将 返回的赔付内容进行替换，将赔付金额设置成 订单的原始金额
                    afterSaleItem.put("value", jxOrderDo.getTotalPrice());
                }
                afterSaleItem.remove("flag");
                // 设置每个售后项的 显示编号
                afterSaleItem.put("num", k);
            }

            return Result.ok(afterSales);
        }
        return Result.error("获取售后服务标准及补偿金额是失败");
    }


    /**
     * 接口 3.21 提交售后申请工单，调用参数中传递 售后申请详情
     * @param request
     * @return
     */
    @PostMapping("/submitAfterSaleService")
    public Result<?> submitAfterSaleService(
            HttpServletRequest request,
            @RequestBody() JxAfterSalesVo afterSalesVo) {

        JxAfterSalesDo jxAfterSalesDo = new JxAfterSalesDo();
        jxAfterSalesDo.setOrderId(afterSalesVo.getOrderId());
        jxAfterSalesDo.setAfterSaleItemId(afterSalesVo.getAfterSaleItemId());
        jxAfterSalesDo.setAfterSaleItemTitle(afterSalesVo.getAfterSaleItemTitle());
        jxAfterSalesDo.setValue(afterSalesVo.getValue());
        jxAfterSalesDo.setState("受理中");
        jxAfterSalesDo.setComments("受理中");

        int insertCount = jxAfterSalesMapper.insert(jxAfterSalesDo);
        JSONObject resultData = new JSONObject();
        if (insertCount == 1) {
            resultData.put("afterSaleId", jxAfterSalesDo.getId());
            resultData.put("msg", "售后申请成功，将尽快为您处理");
            return Result.ok(resultData);
        } else {
            resultData.put("afterSaleId", "");
            resultData.put("msg", "售后申请提交失败，请联系客服人员进行处理");
            return Result.error("售后申请提交失败，请联系客服人员进行处理", resultData);
        }
    }

    /**
     * 接口 3.22 提交售后申请工单，调用参数中传递 售后申请详情
     * @param request
     * @return
     */
    @GetMapping("/queryAfterSaleProcess")
    public Result<?> queryAfterSaleProcess(
            HttpServletRequest request,
            @RequestParam("afterSaleId") String afterSaleId) {

        JxAfterSalesDo afterSalesDo = jxAfterSalesMapper.selectById(afterSaleId);
        JSONObject resultData = new JSONObject();
        if (afterSalesDo == null) {
            resultData.put("state", "未知");
            resultData.put("comments", "无法查询到该售后工单的信息，请联系客服人员进行处理");
            return Result.error("无法查询到该售后工单的信息，请联系客服人员进行处理",resultData);
        } else {
            resultData.put("state", afterSalesDo.getState());
            resultData.put("comments", afterSalesDo.getComments());
            return Result.ok(resultData);
        }
    }
}
